module Alglib
    class LinearRegression
        attr_reader :model, :cases, :ivars
        # Creates a Linear Regression object based on a Matrix
        # EXAMPLE: 
        #   require 'alglib'
        #   matrix=Matrix[[2,3,4],[2,5,5],[1,5,3],[4,6,5]]
        #   lr=Alglib::LinearRegression.build_from_matrix(matrix)
        #     => #<Alglib::LinearRegression:0x7ffaf6c05dc0 @model=#<Alglib_ext::LinearModel:0x7ffaf6c05e60>, @cases=4, @report=#<Alglib_ext::LrReport:0x7ffaf6c05e10>, @ivars=2>
        #     lr.coeffs
        #     => [0.585714285714286, -0.0142857142857142]

        def self.build_from_matrix(matrix)
            raise "Argument should be a matrix" unless matrix.is_a? Matrix
            cases=matrix.row_size
            ivars=matrix.column_size-1
            lm=Alglib_ext::LinearModel.new
            lr=Alglib_ext::LrReport.new
            am=matrix.to_alglib_matrix
            Alglib_ext::lrbuild(am,cases,ivars,lm,lr)
            self.new(lm,lr,cases,ivars)
        end
        # Use with care...
        def initialize(lm,lr,cases,ivars)
            @model=lm
            @report=lr
            @cases=cases
            @ivars=ivars
        end
        # Constant value. a on
        # y= a+b1x1+b2x2...
        
        def constant
            v=Alglib_ext::Real1dArray.new
            Alglib_ext::lrunpack(@model,v, @ivars);
            Alglib_ext.real1d_to_array(v).slice(-1)
        end
        # Array with b coeffs.  
        def coeffs
            v=Alglib_ext::Real1dArray.new
            Alglib_ext::lrunpack(@model,v, @ivars);
            Alglib_ext.real1d_to_array(v)[0,v.size]
        end
        # Predict an y value based on an array of predictors.
        def process(vector)
            Alglib_ext::lrprocess(@model,vector);
        end
        # A wrapper for lm_report
        def report
            {:c=>@report.c,
                :rmserror=>@report.rmserror,
                :avgerror=>@report.avgerror,
                :avgrelerror=>@report.avgrelerror,
                :cvrmserror=>@report.cvrmserror,
                :cvavgerror=>@report.cvavgerror,
                :cvavgrelerror=>@report.cvavgrelerror,
                :ncvdefects=>@report.ncvdefects,
                :cvdefects=>@report.cvdefects
            }
        end
        
    end
end
